(function($){
	/**
	 *  图片导航栏的事件监听
	 *  元素：
	 *  a, 导航栏 ul 元素
	 *	b，导航栏 ul 左边 a 元素
	 * 	c，导航栏 ul 右边 a 元素
	 *  d，导航栏 ul 底部小滑块 左边 b 元素
	 * 	e，导航栏 ul 底部小滑块 右边 b 元素
	 * 	f，导航栏 ul 底部小滑块 中间 span 元素
	 *  参数：
	 *  1，图片个数 n
	 *  2, 图片长度
	 *  3, 导航栏的总长
	 *
	 *
	 *
	 * 	为了保证自定义小滑块的拖动操作正常，
	 *  自定义小滑块的位置不能超过窗口显示的位置
	 *
	 *
	 *  已知：
	 *  1 显示部分的宽度 A
	 *  
	 *
	 *
	 *  计算求得：
	 *  1 滚动滑块的宽度。最小宽度为 36。
	 *  2 小滑块移动 x 距离， 整体导航图移动 y 距离。需要求的是 y 的值。
	 *
	 */
	 
	var img_numb = 10,
		img_width = 100 + 6,
		sum_length = img_numb * img_width;
	
	/**
	 * 	Type of all parameters is htmlElement
	 *	@param lt_a  Left navigation link
	 *  @param rt_a	 Right navigation link
	 *  @param wp_b	 MoveBar use for monitor
	 *  @param md_s  Middle part of bottom navigation button
	 *  @param ul	 The thumb navigation 
	 *	@param a	 MoveBar use for auxiliary monitor
	 * 	@param nav_bg Rolling slide
	 */
	
	var ImgBox = function(options){
		
		this.lt_a = options.link_lt_a;
		this.rt_a = options.link_rt_a;
		this.wp_b = options.btn_bg;
		this.md_s = options.btn_md_s;
		this.wp_u = options.thumb;
		this.ul = options.thumb_ul;
		this.a = options.nav_btn;
		this.nav_bg = options.nav_bg;
		this.organ = options.nav_li_ar;
		this.img_p = options.img_prev;
		this.img_n = options.img_next;
		this.img_l = options.img_load;
		this.img = options.img;
		this.img_w = this.img.parentNode;
		
		this.init();
		this.monitor();
	};
	
	ImgBox.prototype = {
		init: function(){
			//收缩导航图片总个数
			this.img_numb = 10;
		    //每页显示导航图片的个数
			this.page_img = 4;
			//一个图片的宽度
			this.img_width = img_width;
		    //收缩导航图的总长度
			this.sum_length = sum_length;
		    //自定义滑块所在滑轨的总长度
		    //‘aider.js’中定义的‘getStyle’这个方法有时（IE）返回‘auto’
		    //this.trackLength = parseInt($.getStyle(nav_bg, 'width'));
			this.trackLength = nav_bg.clientWidth;
		    //滑块的长度，这个应该有个算法，根据图片的个数确定这里的长度
		    //但是应该有个最大值和最小值，最小值应该就是36
			this.barLength = this.getBarLength();
		    //滑块可以滑动的最大距离
			this.maxBarTo = this.trackLength - this.barLength;
			//收缩导航栏可见的宽度
			this.thumb = this.wp_u.clientWidth;
			//收缩导航图片最大的偏移值
			this.maxImgTo = this.sum_length - this.thumb;
			//滚动条每移动一个单位，上边显示部分相应的移动 scale 单位
			this.scale = ((this.sum_length - this.thumb)/this.maxBarTo).toFixed(2);
			//记录选中的收缩图
			this.activeId = 0;
			$.setStyle(this.a, 'width', this.barLength + 'px');
		},
		
		monitor: function(){
			var wpHandler = $.bind(this.wpHandler, this),
				mdHandler = $.bind(this.mdHandler, this),
				ltHandler = $.bind(this.ltHandler, this),
				rtHandler = $.bind(this.rtHandler, this),
				leHandler = $.bind(this.leHandler, this),
				reHandler = $.bind(this.reHandler, this),
				bgHandler = $.bind(this.bgHandler, this),
				ipHandler = $.bind(this.ipHandler, this),
				inHandler = $.bind(this.inHandler, this),
				that = this;
			//Monitor a event
			$.helpe.addEvent(this.a, 'click',function(e){
				e.preventDefault();
			});
			
			//Monitor wp_b event
			$.helpe.addEvent(this.wp_b, 'click', wpHandler);
			
			//Monitor md_s event
			$.helpe.addEvent(this.md_s, 'mousedown', mdHandler);
			
			//Cover click event
			$.helpe.addEvent(this.md_s, 'click', function(e){
				e.preventDefault();
				e.stopPropagation();
			});
			
			//Monitor lt_a event
			$.helpe.addEvent(this.lt_a, 'mousedown', ltHandler);
			$.helpe.addEvent(this.lt_a, 'mouseup', leHandler);
			//Monitor rt_a event
			$.helpe.addEvent(this.rt_a, 'mousedown', rtHandler);
			$.helpe.addEvent(this.rt_a, 'mouseup', reHandler);
			
			$.helpe.addEvent(this.lt_a, 'click', function(e){
				e.preventDefault();
				e.stopPropagation();
			});
			$.helpe.addEvent(this.rt_a, 'click', function(e){
				e.preventDefault();
				e.stopPropagation();
			});
			
			//Monitor nav_bg event
			$.helpe.addEvent(this.nav_bg, 'click', bgHandler);
			
			for(var i=0; i<this.organ.length; i++){
				this.organ[i].helpid = i;
				
				$.helpe.addEvent(this.organ[i], 'click', function(e){
					if(that.activeId != this.helpid){
						that.organ[that.activeId].className = '';
						this.className = 'active';
						//一个小屁算法
						that.adjustScroll(this.helpid);
						that.activeId = this.helpid;
						
						var url = this.attributes['data-url'].value;
						that.imageShow(url);
					}
					e.preventDefault();
					e.stopPropagation();
				});
			}
			
			$.helpe.addEvent(this.img_p, 'click', ipHandler);
			$.helpe.addEvent(this.img_n, 'click', inHandler);
		},
		/**
		 *  Image onload event
		 * 	Image complete property
		 */
		imageShow: function(url){
			var img = new Image(),
				that = this;
			img.onerror = function(){
				alert('er... error!');
			};
			img.src = url;
			$.setStyle(this.img_l, 'display', 'block');
			if(!img.complete){
				img.onload = function(){
					$.setStyle(that.img_l, 'display', 'none');
					that.nodeEmpty(that.img_w);
					that.scaledDown(img);
					that.img_w.appendChild(img);
					img.onload = null;
				};
			}else{
				$.setStyle(this.img_l, 'display', 'none');
				this.nodeEmpty(this.img_w);
				this.scaledDown(img);
				this.img_w.appendChild(img);
				img.onload = null;
			}
		},
		
		nodeEmpty: function(parentNode){
    		while(parentNode.firstChild){
      			var oldNode = parentNode.removeChild(parentNode.firstChild);
       			oldNode = null;
     		}
  		},
		
		scaledDown: function(img){
			var maxWidth = 480,
				maxHeight = 380,
				width = img.width,
				height = img.height,
				w, h;
			
			if(width > maxWidth){
				w = maxWidth;
				h = ((height/width)*maxWidth).toFixed(2);
				while(h > maxHeight){
					w -= 10;
					h = ((height/width)*w).toFixed(2);
				}
				img.width = w;
				img.height = h;
			}
			if(height > maxHeight){
				h = maxHeight;
				w = ((width/height)*maxHeight).toFixed(2);
				while(w > maxWidth){
					h -= 10;
					w = ((width/height)*h).toFixed(2);
				}
				img.width = w;
				img.height = h;
			}
		},
		/**
		 *  Get width of barLength
		 *  bar_width = (units_per_page / total_units) * rail_length
		 *  interesting ... ^_^
		 */
		getBarLength: function(){
			var width =  Math.floor((this.page_img / this.img_numb) * this.trackLength),
				barLength;
			
			width < 36 ? barLength = 36 : barLength = width;
			return barLength;
		},
		/**
		 *  往右阅读时，最少保留两个未阅读的图片
		 *  往左阅读是，最少保留一个未阅读的图片
		 *  0  0
		 *  1  0
		 *  2  1u
		 *  3  2u
		 *  4  3u
		 *  5  4u
		 *  6  5u
		 *  7  6u
		 *  8  6u
		 *  9  6u
		 */
		adjustScroll: function(index){
			if(this.img_numb < 5) return;
			if(index < 1) return;
			if(index > this.img_numb - 2) return;
			var init = -(parseInt($.getStyle(this.ul, 'left'))),
				first = parseInt($.getStyle(this.a, 'left')),
				result = (index - 1) * this.img_width,
				change = result - init,
				offset = change/this.scale;
			if(index == 1){
				change = -init;
				offset = -first;
			}
			if(index == this.img_numb - 3 || index == this.img_numb - 2){
				change = this.maxImgTo - init;
				offset = this.maxBarTo - first;
			}
			this.proEffect(this.a, first, offset);
			this.proEffect(this.ul, -init, -change);	
		},
		/**
		 *  Boundary treatment
		 */
		borderScroll: function(dir){
			var init = -(parseInt($.getStyle(this.ul, 'left'))),
				first = parseInt($.getStyle(this.a, 'left')),
				change, offset;
			if(dir > 0){
				change = -init;
				offset = -first;
			}else{
				change = this.maxImgTo - init;
				offset = this.maxBarTo - first;
			}
			this.proEffect(this.a, first, offset);
			this.proEffect(this.ul, -init, -change);
		},
		/**
		 *  MoveBar move a small step
		 */
		smallStep: function(step){
			var aInitL = parseInt($.getStyle(this.a, 'left')),
				to;
			
			if(step < 0){
				(aInitL += step) < 0 ? to = '0' : to = aInitL;
			}else{
				(aInitL += step) > this.maxBarTo ? to = this.maxBarTo : to = aInitL;
			}
			$.setStyle(this.a, 'left', to + 'px');
			$.setStyle(this.ul, 'left', (-to * this.scale + 'px'));
		},
		/**
		 *  MoveBar move one step
		 */
		oneStep: function(direc){
			var ainit = parseInt($.getStyle(this.a, 'left')),
				achange = ainit + (this.img_width/this.scale).toFixed(2)*direc,
				uinit = -(parseInt($.getStyle(this.ul, 'left'))),
				uchange = uinit + this.img_width*direc,
				ag, ug;
				
			achange < 0 ? 
				ag = -ainit :
				achange > this.maxBarTo ? 
					ag = this.maxBarTo - ainit :
					ag = achange - ainit;
			
			uchange < 0 ?
				ug = -uinit :
				uchange > this.maxImgTo ?
					ug = this.maxImgTo - uinit :
					ug = uchange - uinit;
			
			this.proEffect(this.a, ainit, ag);
			this.proEffect(this.ul, -uinit, -ug);
		},
		/**
		 *  Clear interval of navigation
		 */
		handleClear: function(handler){
			if(handler){
				window.clearInterval(handler);
				handler = null;
			}
		},
		/**
		 * 	Left navigation event handler
		 */
		ltHandler: function(e){
			var that = this;
			this.handleClear(this.leftHandler);
			this.leftHandler = window.setInterval(function(){
				that.smallStep(-2);
			}, 50);
		},
		leHandler: function(e){
			this.handleClear(this.leftHandler);
		},
		/**
		 *  Right navigation event handler
		 */
		rtHandler: function(e){
			var that = this;
			this.handleClear(this.rightHandler);
			this.rightHandler = window.setInterval(function(){
				that.smallStep(2);
			}, 50);
		},
		reHandler: function(e){
			this.handleClear(this.rightHandler);
		},
		/**
		 * 	Two side of scrollBar's click handler
		 */
		wpHandler: function(e){
			var left = $.rect(this.a).left,
				right = $.rect(this.a).right,
				offset = e.clientX - left, to;
				
			if(offset < 0 || e.clientX > right) return;
			if(offset < 15){
				this.oneStep(-1);
			}else{
				this.oneStep(1);
			}
			e.preventDefault();
			e.stopPropagation();
		},
		/**
		 *  ScrollBar's drag handler
		 */
		mdHandler: function(e){
			this.moveHandler = $.bind(this.mdMove, this);
			this.endHandler = $.bind(this.mdEnd, this);
			
			this.eInitX = e.clientX;
			this.aInitL = parseInt($.getStyle(this.a, 'left'));
			
			$.helpe.addEvent(document, 'mousemove', this.moveHandler);
			$.helpe.addEvent(document, 'mouseup', this.endHandler);
			e.preventDefault();
			e.stopPropagation();
		},
		/**
		 *  Mousemove event handler
		 */
		mdMove: function(e){
			var barTo = this.aInitL + (e.clientX - this.eInitX), to;
			barTo > 0 	? 
				barTo < this.maxBarTo ? 
					to = barTo:
					to = this.maxBarTo:
				to = 0;
			
			$.setStyle(this.a, 'left', (to + 'px'));
			$.setStyle(this.ul, 'left', (-to * this.scale + 'px'));
			e.preventDefault();
		},
		/**
		 *  Mouseup event handler
		 */
		mdEnd: function(e){
			$.helpe.removeEvent(document, 'mousemove', this.moveHandler);
			$.helpe.removeEvent(document, 'mouseup', this.endHandler);
		},
		/**
		 *  Slideway click event
		 */
		bgHandler: function(e){
			var change = e.clientX - ($.rect(this.a).left + this.barLength/2),
				begin = parseInt($.getStyle(this.a, 'left')),
				init = -(parseInt($.getStyle(this.ul, 'left'))),
				offset = change * this.scale;
			
			if(begin + change < 0) change = -begin;
			if(begin + change > this.maxBarTo) change = this.maxBarTo - begin;
			
			if(init + offset < 0) offset = -init;
			if(init + offset > this.maxImgTo) offset = this.maxImgTo - init;
			
			this.handleClear(this.a.slideHandler);
			this.handleClear(this.ul.slideHandler);
			this.proEffect(this.a, begin, change);
			this.proEffect(this.ul, -init, -offset);
			e.preventDefault();
			e.stopPropagation();
		},
		
		ipHandler: function(e){
			var index, url;
			this.organ[this.activeId].className = '';
			if(this.activeId - 1 < 0){
				index = this.img_numb - 1;
				this.borderScroll(-1);
			}else{
				index = this.activeId - 1;
				this.adjustScroll(index);
			}
			url = this.organ[index].attributes['data-url'].value;
			this.imageShow(url);
			this.activeId = index;
			this.organ[this.activeId].className = 'active';
			e.preventDefault();
			e.stopPropagation();
		},
		
		inHandler: function(e){
			var index, url;
			this.organ[this.activeId].className = '';
			if(this.activeId + 1 > this.img_numb - 1){
				index = 0;
				this.borderScroll(1);
			}else{
				index = this.activeId + 1;
				this.adjustScroll(index);
			}
			url = this.organ[index].attributes['data-url'].value;
			this.imageShow(url);
			this.activeId = index;
			this.organ[this.activeId].className = 'active';
			e.preventDefault();
			e.stopPropagation();
		},
		
		effect: function(property, begin, change){
			var timer = 0,
				that = this,
				duration = 20,
				effectFun = this.easing['easeOutExpo'];
			
			this.handleClear(this.slideHandler);
			this.slideHandler = window.setInterval(function(){
				if(timer ++ >= duration){
					property.left = begin + change + 'px';
					window.clearInterval(that.slideHandler);
					that.slideHandler = null;
				}else{
					property.left = effectFun(timer, begin, change, duration) + 'px';
				}
			}, 12);
		},
		
		proEffect: function(elem, begin, change){
			var timer = 0,
				that = this,
				duration = 20,
				effectFun = this.easing['easeOutExpo'];
			
			this.handleClear(elem.slideHandler);
			elem.slideHandler = window.setInterval(function(){
				if(timer ++ >= duration){
					elem.style.left = begin + change + 'px';
					window.clearInterval(elem.slideHandler);
					elem.slideHandler = null;
				}else{
					elem.style.left = effectFun(timer, begin, change, duration) + 'px';
				}
			}, 12);
		},
		
		easing: {
			swing : function(t, b, c, d){
				return ((-Math.cos(t / d * Math.PI) / 2) + 0.5) * c + b;
			},
			easeOutExpo: function(t, b, c, d){
				return (t === d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
			}
		}
		
	};
	
	window.ImgBox = ImgBox;
})($$L);